
/**
 * AppleIIGo
 * GCR 3.5" Disk Image class
 * (C) 2008 by Marc S. Ressl (mressl@umich.edu)
 * Released under the GPL
 */

#include "GCRDiskImage.h"

#ifndef GCRDISK35DISKIMAGE_H
#define GCRDISK35DISKIMAGE_H

#define GCRDISK35_TAG_BYTENUM		12
#define GCRDISK35_SECTOR_BYTENUM	0x200
#define GCRDISK35_DISK_SECTORNUM	16 * 2 * (12 + 11 + 10 + 9 + 8)
#define GCRDISK35_DISK_TRACKNUM		(DISK_3_5_TRACKNUM * DISK_3_5_HEADNUM)
#define GCRDISK35_DISK_BYTENUM		(GCRDISK35_DISK_SECTORNUM * \
									GCRDISK35_SECTOR_BYTENUM)

class GCRDisk35DiskImage : public GCRDiskImage {
public:
	static bool isDiskImageValid(UINT32 diskType, UINT32 diskImageByteNum);
	
	GCRDisk35DiskImage(char * diskImagePath,
					   UINT32 diskImageOffset,
					   UINT32 diskImageByteNum,
					   bool isWriteProtectionForced);
	~GCRDisk35DiskImage();
	
protected:
	void getDiskTrack(UINT32 * trackIndex, UINT32 * headIndex, 
					  UINT32 * diskImageTrackByteNum,
					  UINT32 diskImageTrackIndex);
	void getDiskImageTrack(UINT32 * diskImageTrackIndex,
						   UINT32 * diskImageTrackByteNum,
						   UINT32 trackIndex, UINT32 headIndex);
	
	void writeAddressField(UINT32 diskImageTrackIndex, UINT32 sectorIndex);
	void writeDataField(UINT8 * sectorData);
	void writeTrack(UINT32 diskImageTrackIndex, UINT8 * diskImageTrackData);
	
	bool readAddressField(UINT32 diskImageTrackIndex, UINT32 sectorIndex);
	bool readDataField(UINT8 * sectorData);
	bool readTrack(UINT32 diskImageTrackIndex, UINT8 * diskImageTrackData);
	
private:
	UINT32 diskImageOffset;
	
	UINT32 gcrHash[3];
	
	UINT32 getSectorNum(UINT32 diskImageTrackIndex);
	void initGcrHash();
	void shiftGcrHash();
	UINT8 getGcrValue(UINT32 hashIndex, UINT8 value);
	void writeGcrTriplet(UINT8 value0, UINT8 value1, UINT8 value2,
						 bool isLastTriplet);
	void writeGcrHash();
};

#endif
